﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Memo.Electricity.Engine
{
	public class WaitForAudio : CWaitable
	{
		public WaitForAudio(AudioSource source)
			=> ready = () => !source.isPlaying;
	}

	public class CAudioMgr : CSingletonBehaviour<CAudioMgr>
	{
		private AudioSource mBgmSource;
		private Dictionary<string, AudioClip> mClipCache;

		private void Awake()
		{
			GameObject go = new GameObject("BGM Player");
			go.transform.parent = transform;
			go.transform.localPosition = Vector3.zero;

			mBgmSource = go.AddComponent<AudioSource>();
			mBgmSource.loop = true;

			mClipCache = new Dictionary<string, AudioClip>();
		}

		public void PlayOneShot(string path)
		{
			AudioClip clip = LoadClip(path);
			CCoroutineMgr.Inst.StartCoroutine(PlayerOneShot(clip));
		}

		public void PlayBGM(string path)
		{
			mBgmSource.clip = LoadClip(path);
			mBgmSource.Play();
		}

		public void StopAllClip()
		{
			AudioSource[] sources = transform.GetComponentsInChildren<AudioSource>();
			foreach (var source in sources)
				source.Stop();
		}

		public void StopBGM()
		{
			mBgmSource.Stop();
		}

		private AudioClip LoadClip(string path)
		{
			if (!mClipCache.ContainsKey(path))
			{
				AudioClip clip = Resources.Load<AudioClip>(path);
				if (clip == null)
				{
					Debug.LogError($"Load audio faild, path = {path}");
					return null;
				}
				mClipCache.Add(path, clip);
			}
			return mClipCache[path];
		}

		private IEnumerator PlayerOneShot(AudioClip clip)
		{
			var go = new GameObject("OneShot Player");
			go.transform.parent = transform;
			AudioSource source = go.AddComponent<AudioSource>();
			source.PlayOneShot(clip);
			yield return new WaitForAudio(source);
			Destroy(go);
		}

	}
}